NOTE

1.1 make vs new

What make and new are in Go, why memory allocation is needed, how they are used, their differences, and their implementation details.

GoCreated Updated 1 min readhistorical

This is a historical learning note and may contain outdated or incomplete understanding.

1. What They Are

Go built-in functions.

2. Why They Are Needed

Allocate memory space.

Value types can be used after declaration.

func TestVars(t *testing.T) {
	var i int
	var s string
	fmt.Println(i, s)
}
// output
0 

Reference types need memory space to be allocated.

func TestVars2(t *testing.T) {
	var i *int
	fmt.Println(i)
	fmt.Println(*i)

}
// output
<nil>
--- FAIL: TestVars2 (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x5098cf]

3. Usage

3.1. new

Allocate a block of memory, set it to the zero value, and return a pointer to the memory address for that type.

func TestNew(t *testing.T) {
	var i *int
	i = new(int)
	fmt.Println(*i)
}
// output
0

3.1.1. Equivalent to &struct{}

type Stu struct {
	// name
	name string
}

func testNew() {
	f := new(Stu) // actually *f = &Stu{}, so new is generally not used
	f.TestPrintName()
	f.SetName("user")
	f.TestPrintName()
}

3.2. make

Used to create slices, maps, and channels. It allocates a block of memory and initializes it rather than setting it to the zero value (the zero value of these reference types is nil). It returns the value itself instead of a pointer (because slices, maps, and channels are reference types, so there is no need to return pointers to them).

func TestMake(t *testing.T) {
	fmt.Println(makeSlice())
}

func makeSlice() []int {
	return make([]int, 0)
}

4. new vs make

make new
Purpose Allocate heap memory Allocate heap memory
Argument Used to initialize slices, maps, and channels Used to allocate memory for a type and set the memory to its zero value
Return The three reference types themselves A pointer to the type

5. Implementation

5.1. new

func TestNew(t *testing.T) {
	var i *int
	i = new(int)
	fmt.Println(*i)
}
// output
0
  • go tool compile -S
0x0024 00036 (make1_test.go:14)	PCDATA	$0, $1
0x0024 00036 (make1_test.go:14)	PCDATA	$1, $0
0x0024 00036 (make1_test.go:14)	LEAQ	type."".Stu(SB), AX
0x002b 00043 (make1_test.go:14)	PCDATA	$0, $0
0x002b 00043 (make1_test.go:14)	MOVQ	AX, (SP)
0x002f 00047 (make1_test.go:14)	CALL	runtime.newobject(SB)
0x0034 00052 (make1_test.go:14)	PCDATA	$0, $1
0x0034 00052 (make1_test.go:14)	MOVQ	8(SP), AX

It calls runtime.newobject(SB).

5.2. make

func TestMake(t *testing.T) {
	fmt.Println(makeSlice())
}

func makeSlice() []int {
	return make([]int, 0)
}
  • go tool compile -S
0x002f 00047 (make1_test.go:13)	PCDATA	$0, $0
0x002f 00047 (make1_test.go:13)	MOVQ	AX, (SP)
0x0033 00051 (make1_test.go:13)	XORPS	X0, X0
0x0036 00054 (make1_test.go:13)	MOVUPS	X0, 8(SP)
0x003b 00059 (make1_test.go:13)	CALL	runtime.makeslice(SB)
0x0040 00064 (make1_test.go:13)	PCDATA	$0, $1
0x0040 00064 (make1_test.go:13)	MOVQ	24(SP), AX

It calls runtime.makeslice(SB).

6. References

Discussion

Sign in with GitHub to comment. Discussions are stored as GitHub Issues.View on GitHub